#pragma once
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <functional>
#include <cassert>
using namespace std;
class Thread;//声明类


class Context
{
public:
    Thread* this_;

public:
    Context() :this_(nullptr)
    {} 
};


class Thread
{
public:
    typedef std::function<void*(void*)> func_t;
    Thread(func_t func, void* args, int num = 1) 
        :func_(func)
        ,args_(args)
    {
        char name[64];
        snprintf(name, sizeof name, "thread %d", num);
        name_ = name;

        Context* ctx = new Context;
        ctx->this_ = this;

        int n = pthread_create(&tid_, nullptr, start_routine, ctx);  
        sleep(1);
        delete ctx;
        assert(0 == n);
        (void)n;
    } 
    static void* start_routine(void* args)
    {
        Context* ctx = (Context*)args;
        return ctx->this_->run();
    }

    void* run()
    {
        func_(args_);
    }
    int join()
    {
        return pthread_join(tid_, nullptr);
    }
private:
    string name_;
    pthread_t tid_;
    func_t func_;
    void* args_;
};